package main

import (
	"fmt"
	"gofirst/ch08point/nillearn"
)

func swap1(a int, b int) {
	//交换a, b
	c := a
	a = b
	b = c
}

func swap2(a *int, b *int) {
	//交换a, b
	c := *a
	*a = *b
	*b = c
}

func main() {
	a := 10
	b := 20
	swap1(a, b)

	fmt.Printf("a=%d, b=%d\n", a, b) //交换不成功

	//指针 - 对于内存来说，每个字节其实都是有地址的

	fmt.Printf("a的地址：%p\n", &a)

	//现在有一种特殊的变量类型，这个变量智能保存地址值

	var ptrI *int //只能保存int类型变量的地址
	ptrI = &a     //&是取地址符
	fmt.Println(ptrI)

	//*除了声明指针变量，也可以取出该指针的值
	*ptrI = 30
	fmt.Printf("ptrI指向的内存地址是：%p, 该内存存储的值是：%d\n", ptrI, *ptrI)

	//交换a, b
	swap2(&a, &b)
	fmt.Printf("a=%d, b=%d\n", a, b)

	//指针还可以指向数组，指向数组的指针 - 数组指针
	arr := [3]int{1, 2, 3}
	var ptrA *[3]int
	ptrA = &arr
	fmt.Printf("数组arr的指针：%p\n", ptrA)

	//指针数组
	ptrArr := [2]*int{&a, &b} //能够存放三个指针的数组
	fmt.Println("指针数组ptrArr的值：", ptrArr)

	//很多时候都是函数参数的时候指明的类型
	//指针的默认值是nil

	//像python和java等语言都在极力避免指针
	//因为，早期c/c++，提供的指针，给的权限太大，可以进行指针的偏移，指针的运算
	//go语言，没有屏蔽指针，但go在指针上做了大量的限制，相对于c和c++,指针的功能相对受限

	//nil, new, make
	nillearn.NilLearn()
}
